package com.campus.runrun.serviceImpl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campus.runrun.common.exception.CustomException;
import com.campus.runrun.common.exception.ResultCodeEnum;
import com.campus.runrun.common.utils.PageResult;
import com.campus.runrun.dao.ChatListElementDao;
import com.campus.runrun.dao.ChatRecordDao;
import com.campus.runrun.model.entity.ChatListElementEntity;
import com.campus.runrun.model.entity.ChatRecordEntity;
import com.campus.runrun.model.requestvo.ChatRecordQueryParam;
import com.campus.runrun.model.vo.ChatRecordSendVO;
import com.campus.runrun.model.vo.ChatRecordToClientVO;
import com.campus.runrun.service.api.ChatRecordService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
import java.util.Date;

@Service("chatRecordService")
public class ChatRecordServiceImpl extends ServiceImpl<ChatRecordDao, ChatRecordEntity> implements ChatRecordService {

    @Autowired
    private ChatRecordDao chatRecordDao;

    @Autowired
    private ChatListElementDao chatListElementDao;

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 获取点对点的聊天记录
     * @param chatRecordQueryParam
     * @return
     */
    @Override
    @Transactional
    public PageResult obtainRecordsPageByOppositeUserId(ChatRecordQueryParam chatRecordQueryParam) {
        if (chatRecordQueryParam == null) {
            chatRecordQueryParam = new ChatRecordQueryParam();
        }
        if (chatRecordQueryParam.getPage() <= 0) {
            chatRecordQueryParam.setPage(1);
        }
        if (chatRecordQueryParam.getSize() <= 0) {
            chatRecordQueryParam.setSize(1);
        }
        PageHelper.startPage(chatRecordQueryParam.getPage(), chatRecordQueryParam.getSize());
        Page<ChatRecordToClientVO> chatRecordToClientVOPageList = chatRecordDao.getRecordsPageByOppositeUserId(chatRecordQueryParam.getFromUserId(), chatRecordQueryParam.getToUserId());

        // 翻转聊天记录集合
        Collections.reverse(chatRecordToClientVOPageList.getResult());
        PageResult pageResult = new PageResult(chatRecordToClientVOPageList.getResult(),
                                                (int) chatRecordToClientVOPageList.getTotal(),
                                                chatRecordQueryParam.getSize(),
                                                chatRecordQueryParam.getPage());

        pageResult.setList(chatRecordToClientVOPageList.getResult());
        pageResult.setTotalCount( (int) chatRecordToClientVOPageList.getTotal());

        // 将点对点的消息记录设置为已读
        chatRecordDao.setHasReadByFromUserIdAndToUserIdBatch(chatRecordQueryParam.getFromUserId(), chatRecordQueryParam.getToUserId());
        return pageResult;
    }

    /**
     * 1.将一条消息记录插入数据库并返回带有自增主键的chatRechord
     * 2.查询双方是否在聊天列表中
     * @param chatRecordSendVO
     */
    @Override
    public ChatRecordEntity addOne(ChatRecordSendVO chatRecordSendVO) {
        if (StringUtils.isEmpty(chatRecordSendVO.getMessageContent())) {
            throw new CustomException(ResultCodeEnum.NULL_ERROR);
        }
        ChatRecordEntity chatRecord = new ChatRecordEntity();
        BeanUtils.copyProperties(chatRecordSendVO, chatRecord);
        chatRecordDao.insert(chatRecord);
        addChatList(chatRecord.getFromUserId(), chatRecord.getToUserId());
        return chatRecord;
    }

    /**
     * 通过消息id设置消息为已读
     * @param id
     */
    @Override
    public void setHasReadByRecordId(Integer id) {
        ChatRecordEntity chatRecord = new ChatRecordEntity();
        chatRecord.setId(id);
        chatRecord.setHasRead(true);
        this.baseMapper.updateById(chatRecord);
    }


    /**
     * 没有聊天过的添加进聊天列表
     */
    private void addChatList(Integer fromUserId, Integer toUserId) {
        String key1 =  "runrun_chat_key" + Integer.toString( fromUserId) + "--" + Integer.toString(toUserId);

        String key2 = "runrun_chat_key" + Integer.toString( toUserId) +  "--" + Integer.toString(fromUserId);

        boolean checkKeyExist1 = redisTemplate.hasKey(key1);
        boolean checkKeyExist2 = redisTemplate.hasKey(key2);
        ValueOperations valueOperations = redisTemplate.opsForValue();

        if (checkKeyExist1) {
            // 更新数据库中的更新时间
            ChatListElementEntity chatListElement1 = new ChatListElementEntity();
            QueryWrapper<ChatListElementEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("from_user_id", fromUserId);
            queryWrapper.eq("to_user_id", toUserId);
            chatListElement1.setUpdateTime(new Date());
            chatListElementDao.update(chatListElement1, queryWrapper);
        } else {
            // 插入数据坤再插入缓存
            ChatListElementEntity chatListElement2 = new ChatListElementEntity();
            chatListElement2.setFromUserId(fromUserId);
            chatListElement2.setToUserId(toUserId);
            chatListElementDao.insert(chatListElement2);
            // 插入缓存
            valueOperations.set(key1, 1);
        }

        if (checkKeyExist2) {
            // 更新数据库中的更新时间
            ChatListElementEntity chatListElement3 = new ChatListElementEntity();
            QueryWrapper<ChatListElementEntity> queryWrapper = new QueryWrapper<>();

            queryWrapper.eq("from_user_id", toUserId);
            queryWrapper.eq("to_user_id", fromUserId);
            chatListElement3.setUpdateTime(new Date());
            chatListElementDao.update(chatListElement3, queryWrapper);
        } else {
            // 插入数据坤再插入缓存
            ChatListElementEntity chatListElement4 = new ChatListElementEntity();
            chatListElement4.setFromUserId(toUserId);
            chatListElement4.setToUserId(fromUserId);
            chatListElementDao.insert(chatListElement4);

            // 插入缓存
            valueOperations.set(key2, 1);
        }
    }

}